Türkçe

JavaScript'in AbortController'ını kullanarak fetch istekleri, zamanlayıcılar ve daha fazlası gibi asenkron işlemleri etkili bir şekilde nasıl iptal edeceğinizi öğrenin, böylece daha temiz ve performanslı kodlar yazın.

JavaScript AbortController: Asenkron İşlem İptalinde Uzmanlaşma

Modern web geliştirmede asenkron işlemler her yerde karşımıza çıkar. API'lerden veri çekmek, zamanlayıcılar ayarlamak ve kullanıcı etkileşimlerini yönetmek genellikle bağımsız olarak ve potansiyel olarak uzun bir süre çalışan kodları içerir. Ancak, bu işlemleri tamamlanmadan önce iptal etmeniz gereken senaryolar vardır. İşte bu noktada JavaScript'teki AbortController arayüzü devreye girer. DOM işlemlerine ve diğer asenkron görevlere iptal isteklerini bildirmek için temiz ve verimli bir yol sağlar.

İptal Etme İhtiyacını Anlamak

Teknik detaylara girmeden önce, asenkron işlemleri iptal etmenin neden önemli olduğunu anlayalım. Şu yaygın senaryoları göz önünde bulundurun:

AbortController ve AbortSignal'e Giriş

AbortController arayüzü, asenkron işlemleri iptal etme sorununu çözmek için tasarlanmıştır. İki temel bileşenden oluşur:

Temel Kullanım: Fetch İsteklerini İptal Etme

Bir fetch isteğini iptal etmenin basit bir örneğiyle başlayalım:


const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP hatası! Durum: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('Veri:', data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Fetch iptal edildi');
    } else {
      console.error('Fetch hatası:', error);
    }
  });

// Fetch isteğini iptal etmek için:
controller.abort();

Açıklama:

  1. Bir AbortController örneği oluşturuyoruz.
  2. İlişkili AbortSignalcontroller'dan alıyoruz.
  3. signalfetch seçeneklerine iletiyoruz.
  4. İsteği iptal etmemiz gerekirse, controller.abort()'u çağırıyoruz.
  5. .catch() bloğunda, hatanın bir AbortError olup olmadığını kontrol ediyoruz. Eğer öyleyse, isteğin iptal edildiğini anlıyoruz.

AbortError'u Yönetme

controller.abort() çağrıldığında, fetch isteği bir AbortError ile reddedilecektir. Bu hatayı kodunuzda uygun şekilde yönetmek çok önemlidir. Bunu yapmamak, işlenmemiş promise reddine ve beklenmedik davranışlara yol açabilir.

İşte hata yönetimi ile daha sağlam bir örnek:


const controller = new AbortController();
const signal = controller.signal;

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data', { signal });
    if (!response.ok) {
      throw new Error(`HTTP hatası! Durum: ${response.status}`);
    }
    const data = await response.json();
    console.log('Veri:', data);
    return data;
  } catch (error) {
    if (error.name === 'AbortError') {
      console.log('Fetch iptal edildi');
      return null; // Veya hatanın daha yukarıda işlenmesi için fırlatın
    } else {
      console.error('Fetch hatası:', error);
      throw error; // Hatanın daha yukarıda işlenmesi için yeniden fırlatın
    }
  }
}

fetchData();

// Fetch isteğini iptal etmek için:
controller.abort();

AbortError'u Yönetmek için En İyi Uygulamalar:

AbortSignal ile Zamanlayıcıları İptal Etme

AbortSignal, setTimeout veya setInterval ile oluşturulan zamanlayıcıları iptal etmek için de kullanılabilir. Bu, yerleşik zamanlayıcı fonksiyonları doğrudan AbortSignal'ı desteklemediği için biraz daha manuel çalışma gerektirir. İptal sinyalini dinleyen ve tetiklendiğinde zamanlayıcıyı temizleyen özel bir fonksiyon oluşturmanız gerekir.


function cancellableTimeout(callback, delay, signal) {
  let timeoutId;

  const timeoutPromise = new Promise((resolve, reject) => {
    timeoutId = setTimeout(() => {
      resolve(callback());
    }, delay);

    signal.addEventListener('abort', () => {
      clearTimeout(timeoutId);
      reject(new Error('Zamanlayıcı İptal Edildi'));
    });
  });

  return timeoutPromise;
}

const controller = new AbortController();
const signal = controller.signal;


cancellableTimeout(() => {
  console.log('Zamanlayıcı çalıştı');
}, 2000, signal)
.then(() => console.log("Zamanlayıcı başarıyla tamamlandı"))
.catch(err => console.log(err));

// Zamanlayıcıyı iptal etmek için:
controller.abort();

Açıklama:

  1. cancellableTimeout fonksiyonu argüman olarak bir geri çağrı (callback), bir gecikme ve bir AbortSignal alır.
  2. Bir setTimeout ayarlar ve zamanlayıcı ID'sini saklar.
  3. AbortSignal'a abort olayını dinleyen bir olay dinleyicisi ekler.
  4. abort olayı tetiklendiğinde, olay dinleyicisi zamanlayıcıyı temizler ve promise'i reddeder.

Olay Dinleyicilerini İptal Etme

Zamanlayıcılara benzer şekilde, olay dinleyicilerini iptal etmek için de AbortSignal kullanabilirsiniz. Bu, özellikle kaldırılmakta olan bir bileşenle ilişkili olay dinleyicilerini kaldırmak istediğinizde kullanışlıdır.


const controller = new AbortController();
const signal = controller.signal;

const button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log('Butona tıklandı!');
}, { signal });

// Olay dinleyicisini iptal etmek için:
controller.abort();

Açıklama:

  1. signaladdEventListener yöntemine bir seçenek olarak iletiyoruz.
  2. controller.abort() çağrıldığında, olay dinleyicisi otomatik olarak kaldırılacaktır.

React Bileşenlerinde AbortController

React'te, bir bileşen kaldırıldığında asenkron işlemleri iptal etmek için AbortController kullanabilirsiniz. Bu, bellek sızıntılarını ve kaldırılmış bileşenleri güncellemekten kaynaklanan hataları önlemek için çok önemlidir. İşte useEffect kancasını kullanan bir örnek:


import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data', { signal });
        if (!response.ok) {
          throw new Error(`HTTP hatası! Durum: ${response.status}`);
        }
        const data = await response.json();
        setData(data);
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch iptal edildi');
        } else {
          console.error('Fetch hatası:', error);
        }
      }
    }

    fetchData();

    return () => {
      controller.abort(); // Bileşen kaldırıldığında fetch isteğini iptal et
    };
  }, []); // Boş bağımlılık dizisi, bu etkinin yalnızca bileşen yüklendiğinde bir kez çalışmasını sağlar

  return (
    
{data ? (

Veri: {JSON.stringify(data)}

) : (

Yükleniyor...

)}
); } export default MyComponent;

Açıklama:

  1. useEffect kancası içinde bir AbortController oluşturuyoruz.
  2. signalfetch isteğine iletiyoruz.
  3. useEffect kancasından bir temizleme fonksiyonu döndürüyoruz. Bu fonksiyon, bileşen kaldırıldığında çağrılacaktır.
  4. Temizleme fonksiyonu içinde, fetch isteğini iptal etmek için controller.abort()'u çağırıyoruz.

İleri Düzey Kullanım Senaryoları

AbortSignal'ları Zincirleme

Bazen birden fazla AbortSignal'ı bir araya zincirlemek isteyebilirsiniz. Örneğin, alt bileşenlerindeki işlemleri iptal etmesi gereken bir üst bileşeniniz olabilir. Bunu, yeni bir AbortController oluşturarak ve sinyalini hem üst hem de alt bileşenlere geçirerek başarabilirsiniz.

Üçüncü Parti Kütüphanelerle AbortController Kullanımı

AbortSignal'ı doğrudan desteklemeyen bir üçüncü parti kütüphane kullanıyorsanız, kodunuzu kütüphanenin iptal mekanizmasıyla çalışacak şekilde uyarlamanız gerekebilir. Bu, kütüphanenin asenkron fonksiyonlarını AbortSignal'ı yöneten kendi fonksiyonlarınızla sarmalamayı içerebilir.

AbortController Kullanmanın Faydaları

Tarayıcı Uyumluluğu

AbortController, Chrome, Firefox, Safari ve Edge dahil olmak üzere modern tarayıcılarda yaygın olarak desteklenmektedir. En son bilgiler için MDN Web Docs'taki uyumluluk tablosunu kontrol edebilirsiniz.

Polyfill'ler

AbortController'ı doğal olarak desteklemeyen eski tarayıcılar için bir polyfill kullanabilirsiniz. Polyfill, eski tarayıcılarda daha yeni bir özelliğin işlevselliğini sağlayan bir kod parçasıdır. İnternette birkaç AbortController polyfill'i mevcuttur.

Sonuç

AbortController arayüzü, JavaScript'te asenkron işlemleri yönetmek için güçlü bir araçtır. AbortController kullanarak, iptal işlemlerini zarif bir şekilde yöneten daha temiz, daha performanslı ve daha sağlam kodlar yazabilirsiniz. API'lerden veri çekiyor, zamanlayıcılar ayarlıyor veya olay dinleyicilerini yönetiyor olun, AbortController web uygulamalarınızın genel kalitesini artırmanıza yardımcı olabilir.

İleri Okuma